(function(window) {
	'use strict';
	var $ = window.$,
		Vue = window.Vue,
		METHODS = ["GET", "POST"],
		toString = Object.prototype.toString,
		defaults = {
			token: ""
		},
		Loading = ELEMENT.Loading.service,
		vue_ = new Vue();

	/*拦截button点击提交*/
	/*document.body.addEventListener("click", function(e){
		if(e.target && e.target.nodeName.toUpperCase == "DIV") {
		}
	});*/

	function VanyForm(el) {
		if(!el) {
			throw new Error("请传入一个表单ID或者表单DOM对象");
		}
		if(Object.prototype.toString.call(el) === "[object HTMLFormElement]") {
			this.el = el;
		} else {
			el = el.split("#")[1];
			this.el = document.getElementById(el);
		}
	};

	VanyForm.prototype = {
		valid: function(result) {
			var labels = {},
				tempLabels = this.el.getElementsByTagName("label");
			for(var i = 0; i < tempLabels.length; i++) {
				if(this._isClassExits(tempLabels[i], "el-form-item__label")) {
					var labelName = tempLabels[i].getAttribute("for");
					if(labelName) {
						labels[labelName] = tempLabels[i];
					}
				}
			}
			for(var i = 0; i < result.length; i++) {
				var key = result[i].field;
				var message = result[i].message[0];
				if(labels[key]) {
					var parent_ = labels[key].parentNode,
						sibling = labels[key].nextSibling,
						nodeProps = {
							"nodeType": "div",
							"class": "el-form-item__error",
							"innerHTML": message
						};
					this._addClass(parent_, "is-error");
					var div_ = this._createNode(nodeProps);
					sibling.appendChild(div_);
				} else {
					console.log("字段" + key + "需要手工验证");
				}
			}
		},
		reset: function() {
			var errorNode = this.el.getElementsByClassName("el-form-item__error"),
				errorDiv = this.el.getElementsByClassName("is-error");

			while(errorNode.length) {
				errorNode[0].parentNode.removeChild(errorNode[0]);
			}
			while(errorDiv.length) {
				this._removeClass(errorDiv[0], "is-error");
			}
		},
		_getClass: function(el) {
			return el.className.split(" ");
		},
		_addClass: function(el, _class) {
			_class = _class.split(" ");
			var oldClasses = this._getClass(el),
				newClasses = oldClasses.concat(_class).join(" ");
			el.className = newClasses;
			return this;
		},
		_removeClass: function(el, _class) {
			var oldClasses = this._getClass(el);
			_class = _class.split(" ");
			for(var i = 0; i < _class.length; i++) {
				var index_ = this._getClassIndex(el, _class[i]);
				if(index_ !== false) {
					oldClasses.splice(index_, 1);
				}
				el.className = oldClasses.join(" ");
			}
			return this;
		},
		_getClassIndex: function(el, _class) {
			var nodeClasses = this._getClass(el);
			for(var i = 0; i < nodeClasses.length; i++) {
				if(nodeClasses[i] === _class) {
					return i;
				}
			}
			return false;
		},
		_isClassExits: function(el, _class) {
			var isExits = this._getClassIndex(el, _class);
			return isExits !== false;
		},
		_createNode: function(nodeProps) {
			var node_ = document.createElement(nodeProps["nodeType"]);
			node_.setAttribute("class", nodeProps["class"]);
			node_.innerHTML = nodeProps["innerHTML"];
			return node_;
		}
	};

	var VanyAjax_ = function(url, params, method, loadingTarget, userJquery) {
		try {
			defaults.token = VanyAjax.token;
		} catch(e) {
			console.log("无法获取token值");
		}
		if(!url || toString.call(url) !== "[object String]") {
			throw new Error("请求地址不能为空");
		}

		url = url;

		if(METHODS.indexOf(method) < 0) {
			method = "POST";
		}

		params = extend_(defaults, params);
		var self = this,
			promise_ = "";

		if(userJquery) {
			if($ === undefined) {
				throw new Error("如果要使用Jquery的Ajax方法，请引入Jquery。");
			}
			promise_ = $.when($.ajax({
				url: url,
				type: method,
				data: params,
				beforeSend: function() {
					debugger
					if(loadingTarget) {
						self.showLoading(loadingTarget);
					}
				}
			}));
		} else {
			if(method === "GET") {
				promise_ = Vue.http({
					url: url,
					params: params,
					method: method,
					before: function() {
						if(loadingTarget) {
							self.showLoading(loadingTarget);
						}
					}
				});
			} else {
				promise_ = Vue.http({
					url: url,
					emulateJSON: true,
					body: params,
					method: method,
					before: function() {
						if(loadingTarget) {
							self.showLoading(loadingTarget);
						}
					}
				});
			}
		}
		this.promise_ = promise_;
	};

	VanyAjax_.prototype = {
		token: "",
		baseUrl: "",
		version: "0.0.1",
		/**
		 * 成员方法，自动处理了请求异常，只需实现成功方法即可
		 * fn: 回调函数
		 * isShowMessage: 是否显示rspMsg
		 * vueInstance: vue实例
		 * VanyAjaxInstance.done(function(data)){成功业务逻辑代码};
		 */
		done: function(fn, isShowMessage, vueInstance) {
			var self = this,
				type = "success",
				rspMsg = "",
				rspCode = "";
			/*jQuery的Ajax*/
			if(this.promise_.done) {
				this.promise_.done(function(data) {
					if(data.rspCode === "000000") {
						if(vueInstance) {
							fn.call(vueInstance, data.resultData);
						} else {
							fn.call(self, data.resultData);
						}
					} else {
						// TODO 增加Jquery的promise
						type = "error";
					}
					rspMsg = data.rspMsg;
					self.showMessage(isShowMessage, type, rspMsg);
				}).fail(function(err) {
					type = "error";
					rspMsg = err.statusText;
					self.showMessage(true, type, rspMsg);
				});
			}
			/*Vue的Ajax*/
			else {
				this.promise_.then(function(data) {
					data = data.data;
					rspMsg = data.rspMsg;
					rspCode = data.rspCode;
					if(rspCode === "000000") {
						try {
							vueInstance.vanyform.reset();
						} catch(e) {

						} finally {
							vueInstance ? fn.call(vueInstance, data.resultData) : fn.call(self, data.resultData);
						}
					} else {
						type = "error";
						switch(rspCode) {
							// 表单验证不通过
							case "validationErr":
								console.log("表单验证的情况");
								var validateErrMsg = data.validateErrMsg;
								var refs = vueInstance.$refs;
								for(var form_ in refs) {
									if(form_.toLowerCase().indexOf("form") > -1) {
										refs = refs[form_].$el;
										break;
									}
								}
								var form_ = new VanyForm(refs);
								form_.valid(validateErrMsg);
								vueInstance.vanyform = form_;
								isShowMessage = false;
								break;
								// 登录过期，请重新登录本系统
							case "PERMISSIONCONSTANT_SESSIONERROR":
								isShowMessage = true;
								setTimeout(function() {
									logOut();
								}, 1500);
								break;
							case "PERMISSIONCONSTANT_USER_NOPERMISSION":
								isShowMessage = true;
								break;
						}
					}
				}).catch(function(err) {
					type = "error";
					rspMsg = err.statusText;
				}).finally(function(data) {
					self.showMessage(isShowMessage, type, rspMsg);
				});
			}
			return this;
		},
		error: function(fn, vueInstance) {
			// TODO 增加Jquery的promise
			var rspMsg = "";
			this.promise_.then(function(data) {
				data = data.data;
				rspMsg = data.rspMsg;
				if(data.rspCode !== "000000") {
					vueInstance ? fn.call(vueInstance, data) : fn.call(self, data);
				}
			});
		},
		hideLoading: function() {
			var loadings = document.getElementsByClassName("is-loading");
			for(var i = 0; i < loadings.length; i++) {
				if(loadings[i].nodeName === "BUTTON") {
					var thisClass = loadings[i].className.split(" ");
					var loadingIndex = thisClass.indexOf("is-loading");
					if(loadingIndex > -1) {
						thisClass.splice(loadingIndex, 1);
					}
					var icons = loadings[i].getElementsByClassName("el-icon-loading");
					for(var j = 0; j < icons.length; j++) {
						if(icons[j].nodeName === "I") {
							icons[j].parentNode.removeChild(icons[j]);
						}
					}
					loadings[i].className = thisClass.join(" ");
				}
			}
			try {
				this.loadingInstance.close();
			} catch(e) {}
		},
		/**
		 * 提示请求结果——内部方法
		 * isShow: 是否显示，默认显示
		 * type: 消息类型，枚举型 success|error
		 * message: 消息文本
		 * 无返回值
		 * showMessage("error", "请求错误")
		 * clearData：自定义清空弹框内容
		 */
		showMessage: function(isShow, type, message) {
			this.hideLoading();
			if(isShow === false) {
				return;
			}
			if(type == "error") {
				vue_.$confirm(message, {
					type: 'warning',
					showCancelButton: false,
					//cancelButtonText: "取消",
					showConfirmButton: true,
					confirmButtonText: '确定',
					customClass: "notLoadingThis"
				});
				console.log(message)
			} else if(type == "success") {
				vue_.$message({
					type: type,
					message: message
				});
			}
		},
		showLoading: function(target) {
			this.loadingInstance = Loading({
				target: target,
				text: "拼命加载中"
			});
		}
	}

	/**
	 * 将源对象合并到目标对象中去——内部方法
	 * src: 源对象
	 * to: 目标对象
	 * return 目标对象
	 * a = {"a": "a"}
	 * b = {"b": "b"}
	 * extend_(b, a) →
	 * {a: "a", b: "b"}
	 */
	function extend_(src, to) {
		if(to === undefined) {
			to = {};
		}
		for(var key in src) {
			to[key] = src[key];
		}
		return to;
	}

	function logOut() {
		var form = document.createElement("form");
		var input = document.createElement("input");
		form.setAttribute("target", "_self");
		form.setAttribute("method", "post");
		form.setAttribute("action", "/logout");
		input.setAttribute("type", "text");
		input.setAttribute("name", "token");
		input.setAttribute("value", sessionStorage.token);
		form.appendChild(input);
		document.body.appendChild(form);
		form.submit();
		sessionStorage.clear();
	}

	/**
	 * 封装一个Ajax对象
	 * 事先应设置baseUrl和token
	 * VanyAjax.baseUrl = ""
	 * VanyAjax.token = ""
	 * url: 请求地址
	 * params: 请求参数，默认添加token
	 * loadingTarget: 哪个元素要显示等待效果，可以不传
	 * methods: 请求方法，默认POST
	 * userJquery: 是否使用Jquery的Ajax，默认使用Vue的Ajax
	 * return VanyAjax实例
	 * test = VanyAjax("test.json", {userCode: "test"});
	 */
	window.VanyAjax = function(url, params, methods, loadingTarget, userJquery) {
		return new VanyAjax_(url, params, methods, loadingTarget, userJquery);
	};

	window.VanyAjax.prototype = VanyAjax_.prototype;
})(window);

//demo:
//VanyAjax("/base/org/delete", {
//	orgCode: zTree.getSelectedNodes()[0].id  //传参
//}).done(function(data) {   
//done 结果集
//	removeTreeNode(self);
//}, true, this);   //显示true返回值